package com.hgkj.system.service.impl;

import com.hgkj.common.core.constant.DictConstant;
import com.hgkj.common.async.AsyncManager;
import com.hgkj.common.core.enums.DelFlagStatus;
import com.hgkj.common.core.enums.UserStatus;
import com.hgkj.common.core.utils.AssertExceptionUtils;
import com.hgkj.common.core.utils.EncryptUtils;
import com.hgkj.common.core.utils.FailFastUtils;
import com.hgkj.common.core.utils.RandomSaltUtils;
import com.hgkj.system.async.factory.SystemAsyncTaskFactory;
import com.hgkj.system.domain.SysRole;
import com.hgkj.system.domain.SysUser;
import com.hgkj.system.domain.dto.request.AssignUserRole;
import com.hgkj.system.domain.dto.request.UserPasswordRequest;
import com.hgkj.system.domain.dto.request.UserStatusRequest;
import com.hgkj.system.mapper.SysUserMapper;
import com.hgkj.system.mapper.SysUserRoleMapper;
import com.hgkj.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {

    private final SysUserMapper sysUserMapper;
    private final SysUserRoleMapper sysUserRoleMapper;

    public SysUserServiceImpl(SysUserMapper sysUserMapper, SysUserRoleMapper sysUserRoleMapper) {
        this.sysUserMapper = sysUserMapper;
        this.sysUserRoleMapper = sysUserRoleMapper;
    }

    /**
     * 根据用户名查询用户
     *
     * @param userName 账户
     * @return 用户对象
     */
    @Override
    public SysUser selectSysUserByUserName(String userName) {
        return sysUserMapper.selectSysUserByUserName(userName);
    }

    /**
     * 根据用户ID查询用户信息
     *
     * @param userId 用户ID
     * @return SysUser
     */
    @Override
    public SysUser getUserInfoByUserId(long userId) {
        return sysUserMapper.selectSysUserByUserId(userId);
    }

    /**
     * 分页查询用户列表
     *
     * @param user 条件
     * @return list
     */
    @Override
    public List<SysUser> getUserList(SysUser user) {
        return sysUserMapper.selectSysUser(user);
    }

    /**
     * 新增用户
     *
     * @param user data
     * @return rows
     */
    @Override
    public int insertUser(SysUser user) {
        SysUser dbUser = sysUserMapper.selectSysUserByUserName(user.getUserName());
        AssertExceptionUtils.mustNull(dbUser, "用户名重复");

        user.setSalt(RandomSaltUtils.getSalt(true));
        user.setPassword(EncryptUtils.encryptPassword(user.getPassword(), user.getSalt()));
        user.initInsertPropriety();
        return sysUserMapper.insertUser(user);
    }

    /**
     * 修改用户信息
     *
     * @param user data
     * @return rows
     */
    @Override
    public int updateUser(SysUser user) {
        SysUser dbUser = sysUserMapper.selectSysUserByUserName(user.getUserName());
        if (!Objects.isNull(dbUser)) {
            FailFastUtils.notEqualsFailFast(dbUser.getUserId(), user.getUserId(), "用户名重复");
        }
        user.initUpdatePropriety();
        return sysUserMapper.updateUser(user);
    }

    /**
     * 删除用户
     *
     * @param userId flag
     * @return rows
     */
    @Override
    public int deleteUserByUserId(Long userId) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setDelFlag(DelFlagStatus.DELETE.getCode());
        return sysUserMapper.updateUser(sysUser);
    }

    /**
     * 修改用户密码
     *
     * @param passwordRequest password
     * @return rows
     */
    @Override
    public int updatePassword(UserPasswordRequest passwordRequest) {
        SysUser user = new SysUser();
        user.setUserId(passwordRequest.getUserId());
        user.setSalt(RandomSaltUtils.getSalt(true));
        user.setPassword(EncryptUtils.encryptPassword(passwordRequest.getPassword(), user.getSalt()));
        return sysUserMapper.updateUser(user);
    }

    /**
     * 用户状态变更
     *
     * @param request req
     * @return rows
     */
    @Override
    public int freezeUserById(UserStatusRequest request) {
        SysUser user = new SysUser();
        user.setStatus(request.getStatus());
        user.setUserId(request.getUserId());
        int rows = sysUserMapper.updateUser(user);
        if (rows > 0 && UserStatus.DISABLED.getCode().equals(user.getStatus())) {
            // 异步强制下线
            AsyncManager.getInstance().execute(SystemAsyncTaskFactory.forcedOffline(user.getUserId()));
        }
        return rows;
    }

    /**
     * 为用户分配角色
     *
     * @param assignUserRole data
     * @return rows
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignUserRole(AssignUserRole assignUserRole) {
        int removeRows = sysUserRoleMapper.removeByUserId(assignUserRole.getUserId());
        log.info("[删除原有角色数据条数：{},用户ID：{}]", removeRows, assignUserRole.getUserId());
        if (assignUserRole.getRoleIds().length == 0) {
            return;
        }
        int insertRows = sysUserRoleMapper.batchInsert(assignUserRole.getUserId(), assignUserRole.getRoleIds());
        log.info("[分配角色数据条数:{},用户ID:{}]", insertRows, assignUserRole.getUserId());
    }

    /**
     * 查询用户已分配的角色
     *
     * @param userId userID
     * @return list
     */
    @Override
    public Map<String, Object> assignList(Long userId) {
        Map<String, Object> resp = new HashMap<>();
        List<SysRole> allRoles = sysUserRoleMapper.selectAllRoles();
        List<SysRole> roles = allRoles.stream()
                .filter(item -> !Objects.equals(item.getRoleId(), DictConstant.ADMIN_ROLE_ID))
                .collect(Collectors.toList());
        List<Long> roleIds = sysUserRoleMapper.selectRoleIdsByUserId(userId);
        resp.put("allRoles", roles);
        resp.put("roleIds", roleIds);
        return resp;
    }

}
